﻿using System;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;

namespace iPhoneUI.Shell
{
    public class ShellConfig
    {
        private XmlNode m_shellConfig;

        private ShellConfig()
        {
        }

        public ShellConfig(XmlNode config)
        {
            Debug.Assert(config != null);
            m_shellConfig = config;
            if (m_shellConfig.Attributes["FontFamily"] != null)
                _fontFamily = m_shellConfig.Attributes["FontFamily"].InnerText;
        }

        public void SetConfiguration(int screenWidth, int screenHeight)
        {
            // look for a configuration tat matches the resolution
            XmlNode configuration = m_shellConfig.SelectSingleNode(string.Format("configurations/configuration[@Width='{0}'][@Height='{1}']", screenWidth, screenHeight));

            if (configuration == null)
            {
                // if there isn't one fall back to the default
                configuration = m_shellConfig.SelectSingleNode("configurations/configuration[@Name='Active']");
            }
            else
            {
                // now set the active configuration in the xml document so that embedded references pick up the correct values
                configuration = configuration.CloneNode(true);
                ((XmlElement)configuration).SetAttribute("Name", "Active");
                XmlNode active = m_shellConfig.SelectSingleNode("configurations/configuration[@Name='Active']");
                active.ParentNode.ReplaceChild(configuration, active);
            }

            _scale.Width = (float)screenWidth / 240F;
            _scale.Height = (float)screenHeight / 320F;

            Debug.Assert(configuration != null);            
            // and set the static member so code picks up  thec correct values
            _configuration = new ConfigurationConfig(configuration);
        }

        public HostConfig HostConfig
        {
            get
            {
                return new HostConfig(m_shellConfig.SelectSingleNode("host"));
            }
        }

        public PageConfig GetPage(string name)
        {
            return new PageConfig(m_shellConfig.SelectSingleNode(string.Format("page[@Name = '{0}']", name)));
        }

        public static Bitmap CreateImage(string name)
        {
            string path = Path.Combine(ShellConfig.ImagePath, name);
            if (File.Exists(path))
                return new Bitmap(path);

            Debug.Assert(false);
            return new Bitmap(30, 30);
        }

        private static Type _factoryCoClass = Type.GetTypeFromCLSID(new Guid("327ABDA8-072B-11D3-9D7B-0000F81EF32E"));
        public static IImage CreatePerPixelAlphaImage(string name)
        {
            // Load the image with alpha data through Imaging.
            string path = Path.Combine(ShellConfig.ImagePath, name);
            if (File.Exists(path))
            {
                IImagingFactory factory = (IImagingFactory)Activator.CreateInstance(_factoryCoClass);
                IImage image;
                factory.CreateImageFromFile(path, out image);
                Marshal.ReleaseComObject(factory);

                return image;
            }

            return null;
        }

        public static string ImagePath
        {
            get
            {
                return Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase), "Images");
            }
        }

        private static ConfigurationConfig _configuration;
        public static ConfigurationConfig Configuration
        {
            get
            {
                return _configuration;
            }
        }

        public static Font CreateFont(float size, FontStyle style)
        {
            Debug.Assert(_configuration != null);

            return new Font(FontFamily, size, style);
        }

        private static string _fontFamily = "Tahoma";            
        public static string FontFamily
        {
            get
            {
                return _fontFamily;
            }
        }

        private static SizeF _scale = new SizeF(1, 1);
        public static Size ScaleSize(Size size)
        {
            Size sz = Size.Empty;
            sz.Width = ScaleX(size.Width);
            sz.Height = ScaleY(size.Height);
            return sz;
        }

        public static int ScaleX(int x)
        {
            return (int)Math.Round(_scale.Width * (float)x, 0);
        }

        public static int ScaleY(int y)
        {
            return (int)Math.Round(_scale.Height * (float)y, 0);
        }
    }
}
